package com.zf.easyexcel.controller;

import com.zf.easyexcel.constant.MergeInfoExportHeaderEnum;
import com.zf.easyexcel.constant.MergeInfoFieldConstants;
import com.zf.easyexcel.entity.SheetMergeInfo;
import com.zf.easyexcel.utils.ExcelExportUtils;
import com.zf.easyexcel.utils.ExcelMergeUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Zhou Feng
 */
@RestController
@RequestMapping("/excel")
public class ExcelController {

    /**
     * 导出合并后的excel
     */
    @GetMapping("/exportMerge")
    public void exportMerge(HttpServletResponse response) throws IOException {
        // 假数据
        List<LinkedHashMap<String, Object>> dataList = getMergeInfoOrgData();

        // 按照 FIELD_ONE 分组数据
        Map<String, List<LinkedHashMap<String, Object>>> minDataMap = dataList.stream()
                .collect(Collectors.groupingBy(item ->
                                getGroupStr(MergeInfoFieldConstants.SEPARATOR, MapUtils.getString(item, MergeInfoFieldConstants.FIELD_ONE, ""))
                        , LinkedHashMap::new, Collectors.toList()
                ));
        // 按照分组计算单元格合并信息
        // 计算 FIELD_ONE，FIELD_TWO，FIELD_THREE 列的合并信息
        ArrayList<SheetMergeInfo> mergeInfoList = new ArrayList<>();
        int startIndex = 0;
        for (Map.Entry<String, List<LinkedHashMap<String, Object>>> entry : minDataMap.entrySet()) {
            List<LinkedHashMap<String, Object>> tempDataList = entry.getValue();
            mergeInfoList.addAll(ExcelMergeUtils.calRowCellMergeInfo(tempDataList, Arrays.asList(MergeInfoFieldConstants.FIELD_ONE, MergeInfoFieldConstants.FIELD_TWO, MergeInfoFieldConstants.FIELD_THREE), startIndex));
            startIndex += tempDataList.size();
        }
        // 得到合并信息
        Map<String, List<SheetMergeInfo>> mergeInfoMap = mergeInfoList.stream().collect(Collectors.groupingBy(SheetMergeInfo::getFieldName));

        // 获取需要导出的数据
        List<List<Object>> exportDataList = dataList.stream()
                .map(item -> {
                    Collection<Object> collection = item.values();
                    return (List<Object>) new ArrayList<>(collection);
                }).collect(Collectors.toList());
        // 导出数据的头
        List<List<String>> exportHeaderList = MergeInfoExportHeaderEnum.getHeaderMap()
                .values()
                .stream()
                .map(Arrays::asList)
                .collect(Collectors.toList());

        // 表头的行数
        int headerRowNum = 1;
        // 生成合并信息
        ArrayList<CellRangeAddress> cellRangeAddressList = new ArrayList<>();
        Map<Integer, String> fieldMap = MergeInfoExportHeaderEnum.getFieldMap();
        for (Map.Entry<Integer, String> entry : fieldMap.entrySet()) {
            Integer columnIndex = entry.getKey();
            String fieldName = entry.getValue();
            // 获取该列的那些行需要合并
            List<SheetMergeInfo> mergeInfoVOS = MapUtils.getObject(mergeInfoMap, fieldName, new ArrayList<>());
            for (SheetMergeInfo infoVO : mergeInfoVOS) {
                // 生成并设置合并信息
                CellRangeAddress cellRangeAddress = new CellRangeAddress(infoVO.getStartIndex() + headerRowNum, infoVO.getEndIndex() + headerRowNum, columnIndex, columnIndex);
                cellRangeAddressList.add(cellRangeAddress);
            }
        }
        ExcelExportUtils.exportToExcelDynamicHeaderWithMergeInfo("测试", response, exportHeaderList, exportDataList, cellRangeAddressList);
    }

    /**
     * 生成需要计算merge info的数据
     */
    public static List<LinkedHashMap<String, Object>> getMergeInfoOrgData() {
        ArrayList<LinkedHashMap<String, Object>> res = new ArrayList<>();
        for (int i = 1; i <= 20; i++) {
            LinkedHashMap<String, Object> map = new LinkedHashMap<>();
            Map<Integer, String> fieldMap = MergeInfoExportHeaderEnum.getFieldMap();

            for (Map.Entry<Integer, String> entry : fieldMap.entrySet()) {
                Integer columnIndex = entry.getKey();
                String fieldName = entry.getValue();
                if (columnIndex == 0) {
                    map.put(fieldName, "字段1值:" + (i / 10));
                } else if (columnIndex == 1) {
                    map.put(fieldName, "字段2值:" + (i / 5));
                } else if (columnIndex == 2) {
                    map.put(fieldName, "字段3值:" + (i % 21));
                }
            }
            res.add(map);
        }
        return res;
    }

    /**
     * 通过特定分隔符生成组合Key
     */
    public String getGroupStr(String separator, Object... values) {
        StringJoiner sb = new StringJoiner(separator);
        for (Object value : values) {
            sb.add(String.valueOf(value));
        }
        return sb.toString();
    }

}
